package com.example.demo.chat;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.util.concurrent.GlobalEventExecutor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.net.InetSocketAddress;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Netty服务
 *
 * @author JHY
 * @date 2023/03/08
 */
@Slf4j
@Component("NettyAsyncServer")
public class NettyAsyncServer {
    @Value("${netty.host}")
    private String host = "0.0.0.0";
    @Value("${netty.port}")
    private Integer port =8889;


    public static final Map<String, Channel> player=new ConcurrentHashMap<>(1024);

    public static final ChannelGroup GROUP=new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);


    @Async
    public void start() {
        InetSocketAddress socketAddress = new InetSocketAddress(host, port);
        // 主线程池: 用于接收客户端请求连接,不做任何处理
        EventLoopGroup masterGroup = new NioEventLoopGroup();
        // 从线程池: 主线程池会把任务交给他,让其做任务
        EventLoopGroup subGroup = new NioEventLoopGroup();

        try {
            // 创建服务器启动类
            ServerBootstrap server = new ServerBootstrap();
            // 设置主从线程组
            server.group(masterGroup, subGroup)
                    // 设置双向通道
                    .channel(NioServerSocketChannel.class)
                    // 添加子处理器,用于处理从线程池的任务
                    .childHandler(new NettyServerInitializer())
                    .localAddress(socketAddress);
            // 启动服务,并且设置端口号,设置成同步方式
            ChannelFuture future = server.bind(socketAddress).sync();
            log.info("NettyServer启动成功: ws:/{}/ws", socketAddress);
            // 监听关闭的channel,设置成同步方式
            future.channel().closeFuture().sync();
        } catch (Exception e) {
            log.error("NettyServer异常:" + e.getMessage());
        } finally {
            masterGroup.shutdownGracefully();
            subGroup.shutdownGracefully();
        }
    }

}